package com.treasure.mall.biz.service.core.live.impl;

import com.treasure.mall.biz.base.AbstractSearchableCrudService;
import com.treasure.mall.biz.base.SpecificationAndSort;
import com.treasure.mall.biz.dto.BaseSaveDTO;
import com.treasure.mall.biz.dto.BaseSearchDTO;
import com.treasure.mall.biz.dto.common.ChatMessageBodyDTO;
import com.treasure.mall.biz.dto.condition.LiveRoomVideoSearchCondition;
import com.treasure.mall.biz.dto.live.LiveRoomVideoSaveDTO;
import com.treasure.mall.biz.entity.live.LiveRoomPO;
import com.treasure.mall.biz.entity.live.LiveRoomVideoPO;
import com.treasure.mall.biz.entity.live.LiveRoomVideoPO_;
import com.treasure.mall.biz.mapstruct.LiveRoomMapStruct;
import com.treasure.mall.biz.remote.live.TencentIMService;
import com.treasure.mall.biz.remote.live.dto.GeneralMessageDTO;
import com.treasure.mall.biz.remote.live.enums.MessageType;
import com.treasure.mall.biz.repository.live.LiveRoomVideoRepository;
import com.treasure.mall.biz.service.core.live.LiveRoomService;
import com.treasure.mall.biz.service.core.live.LiveRoomVideoService;
import com.treasure.mall.biz.vo.live.LiveRoomVideoVO;
import com.treasure.mall.zbq.common.exception.ApiException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * <p>
 * +---------------------------------------------------------
 * * @package: com.treasure.mall.biz.service.core.live.impl
 * * @author: guomw (guomwchen@foxmail.com)
 * * @date: 2020/9/11 11:38 上午
 * * @since: V1.0.0
 * +---------------------------------------------------------
 * 注意：本内容仅限于内部传阅，禁止外泄以及用于其他的商业目的
 * 
 */
@Service
public class LiveRoomVideoServiceImpl extends AbstractSearchableCrudService<LiveRoomVideoPO, Long> implements LiveRoomVideoService {

    private LiveRoomVideoRepository liveRoomVideoRepository;
    @Autowired
    private TencentIMService imService;
    @Autowired
    private LiveRoomService liveRoomService;

    protected LiveRoomVideoServiceImpl(LiveRoomVideoRepository repository) {
        super(repository);
        liveRoomVideoRepository = repository;
    }

    @Override
    protected SpecificationAndSort<LiveRoomVideoPO> specificationAndSort(BaseSearchDTO searchDTO) {
        LiveRoomVideoSearchCondition condition = (LiveRoomVideoSearchCondition) searchDTO;
        Specification<LiveRoomVideoPO> specification = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            predicates.add(cb.equal(root.get(LiveRoomVideoPO_.deleted), false));
            if (condition.getRoomId() != null) {
                predicates.add(cb.equal(root.get(LiveRoomVideoPO_.roomId), condition.getRoomId()));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

        Sort sort = new Sort(Sort.Direction.DESC, "id");
        return new SpecificationAndSort<>(specification, sort);
    }

    @Override
    public LiveRoomVideoPO save(BaseSaveDTO saveDTO) {
        LiveRoomVideoSaveDTO dto = (LiveRoomVideoSaveDTO) saveDTO;
        if (dto == null) {
            throw new ApiException("无效参数");
        }

        LiveRoomPO liveRoomPO = liveRoomService.findById(dto.getRoomId());
        if (liveRoomPO == null) {
            throw new ApiException("无效参数");
        }
        LiveRoomVideoPO po = LiveRoomMapStruct.INSTANCE.dto2LiveRoomVideoPO(dto);
        po.setPushed(false);
        po.setCreateTime(LocalDateTime.now());
        po.setMerchantId(liveRoomPO.getMerchant().getMerchantId());
        po = save(po);
        return po;
    }

    @Override
    public void resetPushed(Long roomId) {
        liveRoomVideoRepository.resetPushed(roomId);
    }

    @Override
    public void push(Long id) {
        LiveRoomVideoPO po = findById(id);
        if (po != null) {
            po.setPushTime(LocalDateTime.now());
            po.setPushed(true);
            save(po);
            sendVideoMessage(po);
        }
    }

    @Override
    public void close(Long id) {
        LiveRoomVideoPO po = findById(id);
        if (po != null) {
            po.setPushed(false);
            save(po);
            //发送关闭视频消息
            imService.sendMessage(GeneralMessageDTO.builder()
                    .roomId(po.getRoomId())
                    .build(), MessageType.closeVideo);
        }
    }

    private void sendVideoMessage(LiveRoomVideoPO po) {
        LiveRoomPO liveRoomPO = liveRoomService.findById(po.getRoomId());
        if (liveRoomPO == null) {
            throw new ApiException("无效参数");
        }
        //封装消息实体对象
        ChatMessageBodyDTO chatMessageBodyDTO = new ChatMessageBodyDTO();
        chatMessageBodyDTO.setGroupId(liveRoomPO.toStreamName());
        chatMessageBodyDTO.setMessage(po.getVideoUrl());
        chatMessageBodyDTO.setName(po.getTitle());
        chatMessageBodyDTO.setType(MessageType.video.getDesc());
        chatMessageBodyDTO.setTime(LocalDateTime.now());
        //发送聊天消息
        imService.sendChatMessage(chatMessageBodyDTO);
    }

    /**
     * 获取最后一条推送视频数据
     *
     * @param roomId
     * @return
     */
    @Override
    public LiveRoomVideoVO findLastByRoomId(Long roomId) {
        LiveRoomVideoPO po = liveRoomVideoRepository.findFirstByRoomIdAndPushedIsTrueAndDeletedIsFalseOrderByPushTimeDesc(roomId);
        return LiveRoomMapStruct.INSTANCE.liveRoomVideoPO2vo(po);
    }


}
